#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <sqlite3.h>
#include <time.h>

#define PORT 8080
#define BUFFER_SIZE 1024
#define MAX_CLIENTS 10
#define DATABASE_FILE "students.db"
void buffer_to_float(const unsigned char *buffer, int offset, float *value);
// 定义结构体
typedef struct {
    time_t time;
    int id;
    char temperature[3];
    char humidity[3];
    int state_door;
} Student;
// 创建数据库和表
void createDatabase() {
    sqlite3 *db;
    char *err_msg = 0;

    // 打开数据库（如果不存在则创建）
    int rc = sqlite3_open(DATABASE_FILE, &db);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        exit(1);
    }

    // 创建表
    const char *sql = "CREATE TABLE IF NOT EXISTS Students ("
                      "time INTEGER , "
                      "id INTEGER,"
                      "temperature CHAR(2), "
                      "humidity CHAR(2), "
                      "state_door INTEGER);";

    rc = sqlite3_exec(db, sql, 0, 0, &err_msg);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "SQL error: %s\n", err_msg);
        sqlite3_free(err_msg);
        sqlite3_close(db);
        exit(1);
    }

    // 关闭数据库
    sqlite3_close(db);
}

// 添加学生信息到数据库
void addStudentToDatabase(Student student) {
    sqlite3 *db;
    char *err_msg = 0;

    // 打开数据库
    int rc = sqlite3_open(DATABASE_FILE, &db);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        return;
    }

    // 插入数据
    char sql[256];
    snprintf(sql, sizeof(sql),
             "INSERT INTO Students (time, id, temperature, humidity, state_door) "
             "VALUES (%ld, %d, %s, %s, %d);",
             student.time, student.id, student.temperature, student.humidity, student.state_door);

    rc = sqlite3_exec(db, sql, 0, 0, &err_msg);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "SQL error: %s\n", err_msg);
        sqlite3_free(err_msg);
    } else {
        printf("Student added successfully!\n");
    }

    // 关闭数据库
    sqlite3_close(db);
}

// 从数据库中读取所有学生信息
void readStudentsFromDatabase() {
    sqlite3 *db;
    char *err_msg = 0;

    // 打开数据库
    int rc = sqlite3_open(DATABASE_FILE, &db);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        return;
    }

    // 查询数据
    const char *sql = "SELECT * FROM Students;";
    sqlite3_stmt *stmt;

    rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "Failed to fetch data: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        return;
    }

    // 显示查询结果
    printf("\nStudents in database:\n");
    printf("ID\tTemperature\tHumidity\tScore\n");
    printf("--------------------------------------------\n");

    while (sqlite3_step(stmt) == SQLITE_ROW) {
        int time = sqlite3_column_int(stmt, 0);
        int id = sqlite3_column_int(stmt, 1);
        double temperature = sqlite3_column_double(stmt, 2);
        double humidity = sqlite3_column_double(stmt, 3);
        int state_door = sqlite3_column_int(stmt, 4);

        printf("%d\t%d\t%.2f\t\t%.2f\t\t%d\n", time, id, temperature, humidity, state_door);
    }

    // 释放语句对象
    sqlite3_finalize(stmt);

    // 关闭数据库
    sqlite3_close(db);
}

int main() {
    time_t rawtime;
    
    createDatabase();

    Student student1 = {0};
    //time(&rawtime);
    //addStudentToDatabase(student1);
    // 从数据库中读取并显示学生信息
    readStudentsFromDatabase();

    int server_fd, client_fd;
    struct sockaddr_in server_addr, client_addr;
    socklen_t client_addr_len = sizeof(client_addr);
    char buffer[BUFFER_SIZE] = {0};

    // 客户端文件描述符集合
    int client_fds[MAX_CLIENTS];
    for (int i = 0; i < MAX_CLIENTS; i++) {
        client_fds[i] = -1; // 初始化为无效值
    }

    // 创建套接字
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("Socket creation failed");
        exit(EXIT_FAILURE);
    }

    // 绑定套接字到端口
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(PORT);

    if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        perror("Bind failed");
        close(server_fd);
        exit(EXIT_FAILURE);
    }

    // 监听连接
    if (listen(server_fd, 5) < 0) {
        perror("Listen failed");
        close(server_fd);
        exit(EXIT_FAILURE);
    }

    printf("Server is listening on port %d...\n", PORT);

    // 文件描述符集合
    fd_set read_fds;
    int max_fd = server_fd; // 初始最大文件描述符是服务器套接字

    while (1) {
        // 清空文件描述符集合
        FD_ZERO(&read_fds);

        // 添加服务器套接字到集合
        FD_SET(server_fd, &read_fds);

        // 添加客户端套接字到集合
        for (int i = 0; i < MAX_CLIENTS; i++) {
            if (client_fds[i] != -1) {
                FD_SET(client_fds[i], &read_fds);
                if (client_fds[i] > max_fd) {
                    max_fd = client_fds[i]; // 更新最大文件描述符
                }
            }
        }

        // 使用 select 监听文件描述符
        int activity = select(max_fd + 1, &read_fds, NULL, NULL, NULL);
        if (activity < 0) {
            perror("Select failed");
            continue;
        }

        // 检查是否有新的客户端连接
        if (FD_ISSET(server_fd, &read_fds)) {
            if ((client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_addr_len)) < 0) {
                perror("Accept failed");
                continue;
            }

            printf("New client connected. Client FD: %d\n", client_fd);

            // 将新客户端添加到客户端集合
            for (int i = 0; i < MAX_CLIENTS; i++) {
                if (client_fds[i] == -1) {
                    client_fds[i] = client_fd;
                    break;
                }
            }
        }

        // 检查客户端是否有数据可读
        for (int i = 0; i < MAX_CLIENTS; i++) {
            if (client_fds[i] != -1 && FD_ISSET(client_fds[i], &read_fds)) {
                memset(buffer, 0, BUFFER_SIZE);
                ssize_t bytes_received = recv(client_fds[i], buffer, BUFFER_SIZE, 0);

                if (bytes_received < 0) {
                    perror("Recv failed");
                    close(client_fds[i]);
                    client_fds[i] = -1; // 从集合中移除
                } else if (bytes_received == 0) {
                    printf("Client %d disconnected.\n", client_fds[i]);
                    close(client_fds[i]);
                    client_fds[i] = -1; // 从集合中移除
                } else {
                    printf("Received from client %d: %s\n", client_fds[i], buffer);
                    //printf("%d,%d,%d\n",buffer[0],buffer[1],buffer[4]);
                    if (buffer[0] == 0x5a && buffer[1] == 0x23) {
                        
                        unsigned char CheckSum = 0; // 使用 unsigned char 防止溢出
                        int id = (int)buffer[2]; // 从 buffer[2] 开始提取一个整数
                        char str[20] = {0}; // 用于存储数据
                        int data_length = (int)buffer[4]; // 数据长度
/*
                        // 检查数据长度是否合法
                        if (data_length > 19) {
                            printf("Error: Data length exceeds buffer size.\n");
                            return -1;
                        }
*/
                        // 复制数据并计算校验和
                        for (int i = 0; i < data_length; i++) {
                            str[i] = buffer[i + 5];
                            CheckSum += buffer[i + 5]; // 计算校验和
                            //printf("%d:%d\n",i,str[i]);
                        }
                        //printf("id: %d, data: %s,my_Checksum: %d, Checksum: %d\n", id, str,CheckSum, buffer[data_length + 5]);

                        // 验证校验和
                        if (CheckSum == (unsigned char)buffer[data_length + 5]) {
                            printf("Checksum is valid.\n");

                            // 使用 sscanf 提取数据
                            student1.temperature[0] = str[0];
                            student1.temperature[1] = str[1];
                            student1.temperature[2] = '\0';
                            student1.humidity[0] = str[2];
                            student1.humidity[1] = str[3];
                            student1.humidity[2] = '\0';
                            time(&rawtime);
                            student1.time = rawtime;
                            student1.id = id;
                            addStudentToDatabase(student1);
                            // 打印提取的结果
                            //printf("%d\n",buffer[4]);
                            //printf("%ld\n",rawtime);
                            //printf("温度: %s\n", student1.temperature);
                            //printf("湿度: %s\n", student1.humidity);
                            //printf("Humidity: %s\n",str);
                        } else {
                            printf("Checksum is invalid.\n");
                        }
                      // 打印结果
                        
                        }
                    // 可选：发送响应给客户端
                    //const char *response = "Message received!";
                    for (int j = 0; j < MAX_CLIENTS; j++) {
                        if(j != i){
                            send(client_fds[j], buffer, strlen(buffer), 0);
                        }
                    }
                    //send(client_fds[i], response, strlen(response), 0);
                }
            }
        }
    }

    // 关闭服务器套接字（实际上不会执行到这里）
    close(server_fd);
    printf("Server shutdown.\n");

    return 0;
}

